<!DOCTYPE html>
<html lang="zh">

<head>

  <title>object_graph_main.html</title>
  <!-- 禁用浏览器缓存机制 -->
  <meta http-equiv="Pragma" content="no-cache">
  <meta http-equiv="Cache-Control" content="no-cache">
  <meta http-equiv="Expires" content="0">

  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <link rel="apple-touch-icon" sizes="180x180" href="images/apple-touch-icon.png">
  <link rel="icon" type="image/png" sizes="32x32" href="images/favicon-32x32.png">
  <link rel="icon" type="image/png" sizes="16x16" href="images/favicon-16x16.png">
  <link rel="stylesheet" type="text/css" href="js/croppie/croppie.min.css">
  <link rel="stylesheet" type="text/css" href="styles/index.css">
  <link rel="stylesheet" type="text/css" href="styles/theme-chalk//index.css">
  <link rel="manifest" href="images/manifest.json">
  <link rel="shortcut icon" href="favicon.ico">
  <script type="text/javascript">
    window.$axops = window.top.$axios

    // console.log('------window.top.g.ApiUrl2-----------',window.top.g.ApiUrl2)
    // var contextPath = 'http://192.168.0.101:20080';
    var contextPath = window.top.g.ApiUrl2;
    window.basePath = '';
    var cells;
    var hexagon, endArrow;
    var pointY = 0;
    // 当前视图是否是时序图视图的标识
    var isTimeSequenceDiagramView = false;

    var urlParams = (function () {
      var result = new Object();
      var params = window.location.search.slice(1).split('&');
      for (var i = 0; i < params.length; i++) {
        idx = params[i].indexOf('=');

        if (idx > 0) {
          result[params[i].substring(0, idx)] = params[i].substring(idx + 1);
        }
      }
      if (typeof result['dev'] == 'undefined') {
        result['dev'] = '1';
      }
      if (typeof result['lang'] == 'undefined') {
        result['lang'] = 'zh';
      }
      return result;
    })();

    // Forces CDN caches by passing URL parameters via URL hash
    if (window.location.hash != null && window.location.hash.substring(0, 2) == '#P') {
      try {
        urlParams = JSON.parse(decodeURIComponent(window.location.hash.substring(2)));

        if (urlParams.hash != null) {
          window.location.hash = urlParams.hash;
        }
      } catch (e) {
        // ignore
      }
    }

    /**
     * 向页面添加meta标签。
     * 用于设置页面的元数据信息，如字符编码、缓存控制等。
     */
    function mxmeta(name, content, httpEquiv) {
      try {
        var s = document.createElement('meta');

        if (name != null) {
          s.setAttribute('name', name);
        }

        s.setAttribute('content', content);

        if (httpEquiv != null) {
          s.setAttribute('http-equiv', httpEquiv);
        }

        var t = document.getElementsByTagName('meta')[0];
        t.parentNode.insertBefore(s, t);
      } catch (e) {
        // ignore
      }
    };
    // 桌面版本的全局变量标识
    var mxIsElectron = window && window.process && window.process.type;

    /**
     * 同步向页面添加脚本文件。
     * 根据开发模式和浏览器支持情况决定加载方式。
     * @param {string} src - 脚本文件的路径
     * @param {Function} onLoad - 脚本加载完成后的回调函数
     * @param {string} id - 脚本标签的ID属性
     * @param {string} dataAppKey - 应用密钥数据属性
     * @param {boolean} noWrite - 是否禁用document.write方式加载
     */
    function mxscript(src, onLoad, id, dataAppKey, noWrite) {
      var defer = onLoad == null && !noWrite;

      if ((urlParams['dev'] != '1' && typeof document.createElement('canvas').getContext === 'function') ||
        onLoad != null || noWrite) {
        var s = document.createElement('script');
        s.setAttribute('type', 'text/javascript');
        s.setAttribute('defer', 'true');
        s.setAttribute('src', src);

        if (id != null) {
          s.setAttribute('id', id);
        }

        if (dataAppKey != null) {
          s.setAttribute('data-app-key', dataAppKey);
        }

        if (onLoad != null) {
          var r = false;

          s.onload = s.onreadystatechange = function () {
            if (!r && (!this.readyState || this.readyState == 'complete')) {
              r = true;
              onLoad();
            }
          };
        }

        var t = document.getElementsByTagName('script')[0];

        if (t != null) {
          t.parentNode.insertBefore(s, t);
        }
      } else {
        document.write('<script src="' + src + '"' + ((id != null) ? ' id="' + id + '" ' : '') + ((dataAppKey != null) ?
          ' data-app-key="' + dataAppKey + '" ' : '') + '></scr' + 'ipt>');
      }
    };

    /**
     * 异步向页面添加脚本文件。
     * 通过动态创建script标签的方式异步加载脚本。
     * @param {string} src - 脚本文件的路径
     */
    function mxinclude(src) {
      var g = document.createElement('script');
      g.type = 'text/javascript';
      g.async = true;
      g.src = src;

      var s = document.getElementsByTagName('script')[0];
      s.parentNode.insertBefore(g, s);
    };
    // 检查本地存储是否可用
    var isLocalStorage = false;

    try {
      isLocalStorage = urlParams['local'] != '1' && typeof (localStorage) != 'undefined';
    } catch (e) {
      // ignored
    }

    var mxScriptsLoaded = false,
      mxWinLoaded = false;

    function checkAllLoaded() {
      if (mxScriptsLoaded && mxWinLoaded) {
        App.main();
      }
    };

    var t0 = new Date();

    // 为本地开发环境更改路径配置
    if (urlParams['dev'] == '1') {
      var geBasePath = './js/grapheditor';
      var mxBasePath = './mxgraph';
      var drawDevUrl = './';

      // 在node.js开发环境中强制包含必要的文件
      mxForceIncludes = true;

      mxscript('utils/index.js')
      mxscript('utils/mxIconSet.js')
      mxscript('utils/connectSelect.js')
      mxscript('utils/customEditCell.js')
      mxscript('utils/mxOverHandler.js')

      mxscript(drawDevUrl + 'js/PreConfig.js');
      mxscript(drawDevUrl + 'js/diagramly/Init.js');
      mxscript(geBasePath + '/Init.js');
      mxscript(mxBasePath + '/mxClient.js');

      // 添加所有依赖于mxClient的JS代码。通过Devel.js的间接方式是必需的，
      // 在某些浏览器中确保mxClient.js（及其异步加载的文件）在Devel.js代码运行时可用。
      mxscript(drawDevUrl + 'js/diagramly/Devel.js');

      // Electron桌面应用相关脚本
      if (mxIsElectron) {
        mxscript('js/diagramly/DesktopLibrary.js');
        mxscript('js/diagramly/ElectronApp.js');
      }

      mxscript(drawDevUrl + 'js/PostConfig.js');
    } else {
      (function () {
        var hostName = window.location.hostname;

        // 支持的域名包括*.draw.io和打包在Quip中的版本
        var supportedDomain = (hostName.substring(hostName.length - 8, hostName.length) === '.draw.io') ||
          (hostName.substring(hostName.length - 13, hostName.length) === '.diagrams.net');
        (hostName.substring(hostName.length - 17, hostName.length) === '.quipelements.com');

        function loadAppJS() {
          mxscript('js/app.min.js', function () {
            mxScriptsLoaded = true;
            checkAllLoaded();

            if (!supportedDomain) {
              mxscript('js/PostConfig.js');
            }

            // Electron桌面应用
            if (mxIsElectron) {
              mxscript('js/diagramly/DesktopLibrary.js', function () {
                mxscript('js/diagramly/ElectronApp.js', function () {
                  mxscript('js/extensions.min.js', function () {
                    mxscript('js/stencils.min.js', function () {
                      mxscript('js/shapes.min.js', function () {
                        mxscript('js/PostConfig.js');
                      });
                    });
                  });
                });
              });
            }
          });
        };

        if (!supportedDomain || mxIsElectron) {
          mxscript('js/PreConfig.js', loadAppJS);
        } else {
          loadAppJS();
        }
      })();
    }

    // 添加基本的错误处理机制
    window.onerror = function () {
      var status = document.getElementById('geStatus');

      if (status != null) {
        status.innerHTML = 'Page could not be loaded. Please try refreshing.';
      }
    };
    mxLoadResources = false;

  </script>
  <style type="text/css">
    body {
      overflow: hidden;
    }

    div.picker {
      z-index: 10007;
    }

    .geSidebarContainer .geTitle input {
      font-size: 8pt;
      color: #606060;
    }

    .geBlock {
      z-index: -3;
      margin: 100px;
      margin-top: 40px;
      margin-bottom: 30px;
      padding: 20px;
    }

    .geBlock h1,
    .geBlock h2 {
      margin-top: 0px;
      padding-top: 0px;
    }

    .geEditor ::-webkit-scrollbar {
      width: 14px;
      height: 14px;
    }

    .geEditor ::-webkit-scrollbar-track {
      background-clip: padding-box;
      border: solid transparent;
      border-width: 1px;
    }

    .geEditor ::-webkit-scrollbar-corner {
      background-color: transparent;
    }

    .geEditor ::-webkit-scrollbar-thumb {
      background-color: rgba(0, 0, 0, .1);
      background-clip: padding-box;
      border: solid transparent;
      border-radius: 10px;
    }

    .geEditor ::-webkit-scrollbar-thumb:hover {
      background-color: rgba(0, 0, 0, .4);
    }

    .geTemplate {
      border: 1px solid transparent;
      display: inline-block;
      _display: inline;
      vertical-align: top;
      border-radius: 3px;
      overflow: hidden;
      font-size: 14pt;
      cursor: pointer;
      margin: 5px;
    }

    #div-data-definition {
      padding: 8px;
    }

    #div-data-definition select {
      font-size: 12px;
    }

    #div-data-definition table {
      margin-top: 10px;
      color: #000000;
      border: 1px solid #eee;
      border-collapse: collapse;
    }

    #div-data-definition table td {
      padding: 6px;
      font-size: 12px;
    }

    #div-data-definition table tbody button {
      margin: 6px;
      padding: 3px;
      cursor: pointer;
      border-radius: 6px;
      border: 1px solid #000000;
      background-color: #ffffff;
    }

    #div-data-domain {
      padding: 8px;
    }

    #div-data-domain select {
      font-size: 12px;
    }

    #div-data-domain table {
      margin-top: 10px;
      color: #000000;
      border: 1px solid #eee;
      border-collapse: collapse;
    }

    #div-data-domain table td {
      padding: 6px;
      font-size: 12px;
    }

    #div-data-domain table tbody button {
      margin: 6px;
      padding: 3px;
      cursor: pointer;
      border-radius: 6px;
      border: 1px solid #000000;
      background-color: #ffffff;
    }

    #rMenu {
      position: absolute;
      visibility: hidden;
      top: 0;
      text-align: left;
      padding: 4px;
      font-size: 12px;
    }

    #rMenu div {
      width: 80px;
      padding: 3px 15px 3px 15px;
      background-color: #FFE6B0;
      border: 1px solid #FFB951;
    }

    #rMenu_event {
      position: absolute;
      visibility: hidden;
      top: 0;
      text-align: left;
      padding: 4px;
      font-size: 12px;
    }

    #rMenu_event div {
      width: 80px;
      padding: 3px 15px 3px 15px;
      background-color: #FFE6B0;
      border: 1px solid #FFB951;
    }

    .right-menu-item {
      color: #000000;
      text-decoration: none;
    }

  </style>
  <!-- IE 9/10二进制XHR的解决方案，参见App.loadUrl -->
  <!--[if (IE 9)|(IE 10)]><!-->
  <script type="text/vbscript">
    Function mxUtilsBinaryToArray(Binary)
				Dim i
				ReDim byteArray(LenB(Binary))
				For i = 1 To LenB(Binary)
					byteArray(i-1) = AscB(MidB(Binary, i, 1))
				Next
				mxUtilsBinaryToArray = byteArray
			End Function

    </script>
  <!--<![endif]-->

  <!-- jQuery库文件 -->
  <script type="text/javascript" src="../static/plugins/jquery/jquery.min.js"></script>
  <!-- zTree树形组件相关文件 -->
  <link rel="stylesheet" href="../static/plugins/zTree/css/zTreeStyle/zTreeStyle.css" type="text/css">
  <link rel="stylesheet" href="../static/plugins/zTree/css/demo.css" type="text/css">
  <link rel="stylesheet" href="/node_modules/element-ui/lib/theme-chalk/index.css" type="text/css">
  <script type="text/javascript" src="../static/plugins/zTree/js/jquery.ztree.core.js"></script>
  <script type="text/javascript" src="../static/plugins/zTree/js/jquery.ztree.exhide.js"></script>
  <script type="text/javascript" src="../static/plugins/zTree/js/jquery.ztree.excheck.js"></script>
  <script type="text/javascript" src="../static/plugins/zTree/js/jquery.ztree.exedit.js"></script>
  <script type="text/javascript" src="../modeler/js/object_graph_main.js"></script>
  <script type="text/javascript" src="../modeler/js/convert-pinyin.js"></script>
  <script type="text/javascript" src="../modeler/js/convert-pinyin.js"></script>
</head>

<body class="geEditor">

  <script>
    window.drawioBus = window.top.$store.state.bus.drawioBus
    window.$axios = window.top.$axios
    // var contextPath = window.top.$apiURL.ApiUrl2;
    let bgUrl;

    /**
     * 重新设置逻辑属性的对象ID。
     * 通过查询服务端获取引用对象的新ID，并更新cell的相关属性。
     * @param {Object} cell - 需要更新的图形单元对象
     * @returns {Promise} 返回Promise对象，处理异步操作
     */
    window.setLogicalPropertyId = function (cell) {
      return new Promise((resolve, reject) => {
        const parmas = {
          object_id: cell.value.getAttribute('objectId'),
          object_type: cell.value.getAttribute('metaId'),
          id: '',
        };
        window.$axios.post(window.top.g.ApiUrl + '/object/selectQuote', window.top.$qs.stringify(parmas)).then((
          res) => {
          cell.getValue().setAttribute('objectId', res.data.id);
          cell.getValue().setAttribute('quoteId', res.data.quoteId);
        })
      })
    }
   
    /**
     * 载入绘图页面内容。
     * 初始化图形编辑器的基本配置和数据，设置全局变量并启动应用。
     * @param {Function} cb - 初始化完成后的回调函数
     */
    window.setupGraph = function setupGraph(cb) {
      let graphData = window.GRAPH_DATA;
      // console.log(graphData)
      window.objectXml = graphData.objectXml;
      window.objectXmlMap = graphData.objectXmlMap;
      window.sizeMap = graphData.sizeMap; //${sizeMap};
      // 是否是仿真页面
      window.isFzPage = window.top.location.href.indexOf('graphSimulation') > -1; //${graphData.isFzPage};
      window.enName = graphData.enName; // '${enName}';
      window.projectId = graphData.projectId; //'${projectId}';
      window.modelId = graphData.modelId; //'${modelId}';
      window.frameworkCode = graphData.frameworkCode; //'${modelId}';
      window.productId = graphData.productId; //'${productId}';
      // window.attrClassifications = graphData.classification; //'${classification}';
      window.modelType = graphData.modelType;
      window.maxLifeHeight = graphData.maxLifeHeight;
      window.isGuideModel = !!graphData.xmlData

      function callback () {
        mianCallBack.apply(null, arguments)
        cb && cb.apply(null, arguments);
        Promise.resolve().then(openGraph)
      }
      App.main(callback);
    };

    /**
     * 打开和初始化绘图画布。
     * 设置数字代理对象、通信通道，并根据模式加载图形数据。
     */
    window.openGraph = function openGraph() {
      const Channel = window.parent.$channel
      // 操作这个代理对象
      window.numberProxy = new Proxy(
        {
          // 定义maxBigNum变量，修复生成名称数字重复问题
          maxBigNum: {},
          // 定义元素右下角的数字，保持状态
          maxSuffixCodeNum: {},
        },
        {
          set(target, key, value) {
            const oldV = target[key];
            if (oldV !== value) {
              Channel.send('DRAWIO_NUMBER', {
                type: key,
                data: { [key]: value, },
              });
            }
            return Reflect.set(target, key, value);
          },
        },
      );
      const numTypes = ['maxBigNum', 'maxSuffixCodeNum'];
      Channel.listen('DRAWIO_NUMBER', ({data: {data, type}})=> {
        if (numTypes.includes(type)) {
          window.numberProxy[type] = data[type];
        }
      });

      if (!window.sidebarStructure) {
        drawioBus.$emit('graphOpenEnd');
      }

      if(window.isGuideModel) {
        setGuideInfo(); // 向导模式的处理
      }else {
        setDrawioInfo();
      }


      function setGuideInfo() {
          window.isSetingGraphXml = true;
          window.SAVE_URL = window.top.g.ApiUrl2 + '/metaModel/saveGraphPage';
          // 向导模式下，根据状态设置cell的颜色相关样式
          const xmlHtml = myEditor.guideEvent.setCellStyle(window.GRAPH_DATA.xmlData);

          window.myEditor.editor.setGraphXml(xmlHtml.documentElement);

          window.EditorUi.prototype.updateSidebar.call(myEditor); // 更新绘图组件
          window.isSetingGraphXml = false;
          // window.top.document.querySelector('.drawioContainer').style.visibility = 'visible';
      }


      function getQueryString(name) {
        const urlString = window.location.href;
        const url = new URL(urlString)
        return url.searchParams.get(name)
      }

      function setFzPageArr(newModelId, name, newModelIdAndName) {
        let cellsNameArr = [];
        let cellsIdArr = [];
        let cells = window.myEditor.editor.graph.getVerticesAndEdges();
        // 时序图会有名字重复 状态图不会，所以判断是statemachineModelId+name
        let index = window.top.fzPageArr.findIndex(i => (i.statemachineModelId + i.name) === newModelIdAndName);
        if (window.top.fzPageArr[index].isUmlLifeLine) {
          // 存储对应的时序图建模元素
          window.top.fzUmlLifelineCells[index] = cells;
          // 时序图删除页面上非时序图元素
          var delCells = cells.filter((cell, index) => {
            if (index === 0) return false;
            return !(cell.style && cell.style.indexOf("shape=umlLifeline;") > -1);
          })
          myEditor.editor.graph.setCellStyles('deletable', 1, delCells);
          window.myEditor.editor.graph.removeCells(delCells);
        } else {
          // 存储对应的状态图建模元素
          window.top.fzStateCells[index] = cells;
        }
        if (cells.length !== 0) {
          cells.forEach((cell) => {
            if (cell.value && typeof cell.value !== 'string') {
              const cellName = cell.value.getAttribute("name");
              const cellId = cell.value.getAttribute("objectId");
              cellsNameArr[cellName] = cell;
              cellsIdArr[cellId] = cell;
              if (cell.style && cell.style.indexOf("shape=umlLifeline;") > -1) {
                // console.log('时序图');
                // cell.geometry.y = 0;
                window.myEditor.editor.graph.refresh();
              }
            }
          })
        }
        window.top.fzCellData[index] = {
          name: name,
          cellsNameArr: cellsNameArr,
          cellsIdArr: cellsIdArr,
        };
        // // console.log(window.top.fzUmlLifelineCells)
        // // console.log(window.top.fzStateCells)
        // // console.log(window.top.fzCellData)
      }

      function setDrawioInfo() {
        let newModelId
        if (getQueryString('modelId')) {
          newModelId = getQueryString('modelId');
          window.modelId = newModelId;
          // 设置仿真标识的 statemachineModelId 重要！！！
          window.statemachineModelId = newModelId;
        } else {
          window.modelId = window.top.MODELID;
          newModelId = window.modelId;
        }

        if (!modelId) return
        let data_xml = '';
        window.$axios.post(window.OPEN_URL, {
          data: {
            'modelId': modelId
          },
        }, {
          headers: {
            'modelId': modelId,
          }
        }).then((data) => {
          if (typeof window.myEditor != 'undefined') {
            if (data.statusCode === 200) {
              window.isSetingGraphXml = true
              window.myEditor.editor.graph.model.beginUpdate();
              try {
                if (data.data != null) {
                  data_xml = data.data.xml;
                  if (data_xml != null && data_xml.length > 50) {
                    const xml = window.myEditor.editor.graph.zapGremlins(mxUtils.trim(data_xml));
                    window.myEditor.editor.setGraphXml(mxUtils.parseXml(xml).documentElement);
                    if (getQueryString('modelId')) {
                      setFzPageArr(newModelId, getQueryString('instanceName'), newModelId + getQueryString(
                        'instanceName'));
                    }
                    window.myEditor.breadcrumb = new BreadCrumb()
                    window.myEditor.breadcrumb.updated()
                  }
                  //设置背景图
                  if (data.data.bgUrl != null && data.data.bgUrl.length > 0) {
                    bgUrl = data.data.bgUrl;
                    const img = new Image();
                    img.onload = function () {
                      myEditor.editor.graph.refresh();
                    };
                    const src = window.location.protocol + '//' + window.location.host + PICTURE_PATH + '?id=' +
                      data.data.bgUrl;
                    img.src = src;
                    myEditor.setBackgroundImage(img);
                  }
                }
                window.myEditor.editor.undoManager.clear();
                //获得生命线的Y坐标
                var cells = window.myEditor.editor.graph.getVerticesAndEdges();
                for (var id in cells) {
                  if (pointY == 0) {
                    pointY = cells[id].geometry.y;
                  }
                }
                isTimeSequenceDiagramView = isTimeSequenceDiagram();
                pageLeaveAutoSave();
                setTimeout(() => {
                  const undo = window.myEditor.actions.get('undo');
                  const redo = window.myEditor.actions.get('redo');
                  undo.setEnabled(false);
                  redo.setEnabled(false);
                  window.myEditor.editor.undoManager.clear();
                })
              } finally {
                window.myEditor.editor.graph.model.endUpdate();
                drawioBus.$emit('graphInitEnd');
                window.isSetingGraphXml = false
                myEditor.setPageVisible()
              }

            } else {
              window.parent.alertDialog(data.message);
              window.parent.closeCurrentTab();
            }
          }
        })
      }
    }

    /**
     * 查找模型引用。
     * 检查当前选中的对象，获取其引用信息并通知父窗口。
     * @param {Object} graph - 图形编辑器实例
     */
    function findObjectQuote(graph) {
      // console.log('findObjectQuote');
      // TODO判断选择的是否是对象
      const cells = graph.getSelectionCells();
      // console.log(cells);
      if (cells.length === 1) {
        const cell = cells[0];
        if (cell.value != null && typeof (cell.value) == 'object') {
          // console.log(cell);
          // var div = $("#div_attributes_panel");
          // // console.log(div);
          // editCellAttribute(cell, graph);	// 点击打开属性编辑对话框
          const metaId = cell.value.getAttribute('metaId');
          const objectId = cell.value.getAttribute('objectId');

          window.top.GRAPHNODECLICK = {
            eObjectId: metaId,
            objectId: objectId,
            modelId: window.MODELID || window.top.MODELID,
          };;


          //模型引用
          if (window.parent && window.parent.findQuote) {
            window.parent.findQuote(modelId, metaId, objectId);
          }
          //元素追踪
          if (window.parent && window.parent.findElementTrack) {
            window.parent.findElementTrack(modelId, metaId, objectId);
          }
        } else {
          //模型引用
          if (window.parent && window.parent.findQuote) {
            window.parent.findQuote();
          }
        }
      } else {
        //模型引用
        if (window.parent && window.parent.findQuote) {
          window.parent.findQuote();
        }
      }
    }

    /**
     * 修改对象属性。
     * 打开属性编辑对话框，允许用户编辑选中对象的属性。
     * @param {Object} cell - 要编辑的图形单元对象
     * @param {Object} graph - 图形编辑器实例
     */
    function editCellAttribute(cell, graph) {
      // 编辑对象属性
      var type = 'edit';
      // 画布 无样式和value 点击属性不反映
      if (cell.value === undefined && cell.style === undefined) {
        return;
      }
      var personalityObj = getPersonalityAttrs(cell);
      attrDialog(cell, resolveCell(cell), type, function (data) {
        const {id, name, sLabel, lineSourceShowName, lineTargetShowName, label} = data
        if (lineSourceShowName !== null) {
          cell.lineSourceShowName = lineSourceShowName
        }
        if (lineTargetShowName !== null) {
          cell.lineTargetShowName = lineTargetShowName
        }
        if (label !== null && label !== undefined) {
          cell.objectLabel = label
        }
        updateCellAttribute(cell, graph, data);
      }, personalityObj);
    }

    /**
     * 修改Cell对象属性值。
     * 更新单元格的各种属性，包括标签、名称、引用ID等，并同步更新相关的引用对象。
     * @param {Object} cell - 要更新的图形单元对象
     * @param {Object} graph - 图形编辑器实例
     * @param {Object} data - 包含更新数据的对象
     */
    async function updateCellAttribute(cell, graph, data) {

      const {id, name, sLabel, label, identityCode, caozuoshu, lineSourceShowName, lineTargetShowName} = data
      if (lineSourceShowName !== null) {
        cell.lineSourceShowName = lineSourceShowName
      }
      if (lineTargetShowName !== null) {
        cell.lineTargetShowName = lineTargetShowName
      }

      const valueObj = cell.getValue();

      // 开始设置标签：如果提供了ID且cell还没有objectId，则设置objectId
      if (id && !cell.value.getAttribute("objectId")) {
        valueObj.setAttribute('objectId', id);
      }

      if (caozuoshu != null) {
        valueObj.setAttribute('caozuoshu', caozuoshu);
      }

      if (sLabel !== 'null' && sLabel != null) {
        if (cell.value.getAttribute('display') === "LABEL_LICHENGBEI") {
          if (cell.edges != null) {
            cell.edges[0].children[0].setValue(sLabel);
            window.myEditor.editor.graph.refresh();
          }
        } else {
          valueObj.setAttribute('sLabel', sLabel);
        }
      }

      const util = new utils()
      await util.putLabel(cell, name, resolveCell(cell))

      graph.getModel().setValue(cell, valueObj);

      if (identityCode != null) {
        valueObj.setAttribute('_suffix', identityCode);
        // graph.addCornerMarkOverlay(cell);
      }
      var objectId = id || objectId; //被修改的对象ID
      //修改被引用的对象的Label
      var vertices = graph.getVerticesAndEdges(true, false);
      $.each(vertices, function (index, vertex) {
        if (typeof (vertex.value) != 'object') {
          return true;
        }
        if (vertex.value.nodeName === 'entity') {
          // 修改引用对象时，同步更改画布上的实体
          if (cell.value.nodeName === 'quote' && cell.value.getAttribute('quoteId') === vertex.value.getAttribute('objectId')) {
            vertex.value.setAttribute('label', cell.value.getAttribute('label'));
            vertex.value.setAttribute('name', cell.value.getAttribute('name'));
            vertex.value.setAttribute('_suffix', identityCode);
            graph.getModel().setValue(vertex, vertex.value);
          }
          return true;
        } else {
          /**
           * 同步修改所有引用对象
           */
          if (vertex.value.nodeName === 'quote' && vertex.value.getAttribute('quoteId') === objectId) {
            var currentValue = vertex.value;
            currentValue.setAttribute('label', valueObj.getAttribute('label'));
            currentValue.setAttribute('name', valueObj.getAttribute('name'));
            currentValue.setAttribute('_suffix', identityCode);
            graph.getModel().setValue(vertex, currentValue);
            return true;
          }
        }
      });

      if (cell.value && cell.value instanceof Object && window.sidebarStructure) {
        // sysml下 修改完属性，更新左侧树节点
        window.sidebarStructure.updateTreeNode()
      }

      graph.redrawLabel(cell);
    }

    function updateCellAttribute2(formData, cell, graph, resp, attrClassSb, isNoLabel) {
      if (formData && cell && graph && resp) {
        //
        var valueObj = cell.getValue();
       var editLabel = getCellLableByEidt2(formData, cell, resp.data.name, attrClassSb);
        // // console.log(editLabel);
        //
        var isNoLableResult = 'noLabel' == isNoLabel;
        if (!isNoLableResult) {
          valueObj.setAttribute('label', editLabel);
          if (resp.data.cfqName != '' && resp.data.cfqName != null && resp.data.cfqName != undefined) {
            valueObj.setAttribute('label', resp.data.cfqName);
          }
          if (resp.data.sentName != '' && resp.data.sentName != null && resp.data.sentName != undefined) {
            valueObj.setAttribute('label', resp.data.sentName);
          }
          if (resp.data.net22 != '' && resp.data.net22 != null && resp.data.net22 != undefined) {
            valueObj.setAttribute('label', resp.data.net22);
          }
          if (resp.data.MNet21 != '' && resp.data.MNet21 != null && resp.data.MNet21 != undefined) {
            valueObj.setAttribute('label', resp.data.MNet21);
          }
          if (cell.value.getAttribute('name_en') == 'zhuangtai') {
            var name = resp.data.name;
            var attrLable = formData.rukoucaozuo;
            if (null == attrLable) {
              attrLable = '';
            }
            var label =
              '<div style="float: left;width: 100%;background-color: rgb(218, 232, 252)"><p style="margin:0px;margin-top:4px;text-align:center;">' +
              '&lt;&lt;' + name + '&gt;&gt;<br/>' + '</p><hr style="margin-bottom: 0px;"/></div>';

            var attrLable = '<div style=\'float: left;width: 100%;margin-top: 5px;\'>' + attrLable + '</div>';
            valueObj.setAttribute('label', label + attrLable);
          }
          if (cell.value.getAttribute('name') == '端口') {
            valueObj.setAttribute('label', '');
          }
        }
        if (resp.data.id) {
          valueObj.setAttribute('objectId', resp.data.id);
        }
        if (resp.data.sLabel != 'null' && resp.data.sLabel != null) {
          valueObj.setAttribute('sLabel', resp.data.sLabel);
        }
        graph.getModel().setValue(cell, valueObj);
        var objectId = resp.data.id || objectId; //被修改的对象ID
        //修改被引用的对象的Label
        var vertices = graph.getChildVertices();
        $.each(vertices, function (index, vertex) {
          if (typeof (vertex.value) != 'object') {
            return true;
          }
          if (vertex.value.nodeName == 'entity') {
            return true;
          } else {
            if (vertex.value.getAttribute('quoteId') == objectId) {
              var currentValue = vertex.value;
              currentValue.setAttribute('label', resp.data.name);
              graph.getModel().setValue(vertex, currentValue);
              return false;
            }
          }
        });
      }

    }

    /**
     * 修改单元格标题。
     * 在现有标签中查找并替换第一个b标签的内容。
     * @param {Object} cell - 要修改的图形单元对象
     * @param {Object} graph - 图形编辑器实例
     * @param {string} labelName - 新的标题名称
     */
    function updateCellLabelName(cell, graph, labelName) {

      if (cell && graph && labelName) {
        const valueObj = cell.getValue();
        const label = valueObj.getAttribute('label');
        // // console.log(valueObj);
        // // console.log(label);
        // 寻找第一个b标签
        const bArray = $(label).find('b');
        if (bArray && bArray.length > 0) {
          // 旧标题
          const oldLabelName = bArray[0].innerText;
          // // console.log(oldLabelName);
          const newLabel = label.replace(oldLabelName, labelName);
          // // console.log(newLabel);
          valueObj.setAttribute('label', newLabel);
          graph.getModel().setValue(cell, valueObj);
        }
      }
    }

    /**
     * 解析cell对象。
     * 将图形单元对象转换为包含模型信息的标准数据结构。
     * @param {Object} baseCell - 要解析的基础图形单元对象
     * @returns {Object} 解析后的包含模型信息的对象
     */
    function resolveCell(baseCell) {
      if (!baseCell) {
        return {}
      }
      let cell = {
        ...baseCell
      }
      if (baseCell && baseCell['GROUP'] && baseCell['GROUP'] === true) {
        // 如果是GROUP类型，使用其第一个子元素
        cell = baseCell.children[0]
      }
      if (cell.value === '' || cell.value === null || !(cell.value instanceof Object)) {
        return {}
      }
      var cellObj = {
        modelId: modelId || window.top.MODELID || '',
        eObjectId: cell.value.getAttribute('metaId') || '',
        objectId: cell.value.getAttribute('objectId') || cell.value.getAttribute('quoteId') ||  '',
        parentId: cell.parent && cell.parent.value instanceof Object && cell.parent.value.getAttribute('objectId') ||
          '',
        quoteId: cell.value.getAttribute('quoteId') || '',
        parentMetaId: cell.parent && cell.parent.value instanceof Object && cell.parent.value.getAttribute(
          'metaId') || '',
        name: cell.value.getAttribute('name') || '',
        label: cell.value.getAttribute('label') || '',
        selectQuote: cell.value.getAttribute('selectQuote') || '', // 是否直接引用
        identityCode: cell.value.getAttribute('_suffix'),
        taskId: top.getProjectStore(top.$constants.TASK_ID),
      };
      var edgeObj = {};
      if (cell.edge == 1) {
        const source = getRealTerminal(baseCell, true)
        const target = getRealTerminal(baseCell, false)
        edgeObj = {
          sourceId: source?.getAttribute('objectId') || '',
          sourceName: source?.getAttribute('name') || '',
          targetId: target?.getAttribute('objectId') || '',
          targetName: target?.getAttribute('name') || '',
        };
      }
      return {
        ...cellObj,
        ...edgeObj
      };
    }

    /**
     * 查看对象属性。
     * 以只读方式显示对象的属性信息，不允许编辑。
     * @param {Object} cell - 要查看的图形单元对象
     * @param {Object} graph - 图形编辑器实例
     */
    function showCellAttribute(cell, graph) {
      // attrDialog(cell, resolveCell(cell), type);
      //   // 编辑对象属性
      var type = 'edit';
      // 画布 无样式和value 点击属性不反映
      if (cell.value === undefined && cell.style === undefined) {
        return;
      }
      var personalityObj = getPersonalityAttrs(cell);
      attrDialog(cell, resolveCell(cell), type, function (data) {
        const { label, lineSourceShowName, lineTargetShowName } = data;
        if (lineSourceShowName !== null) {
          cell.lineSourceShowName = lineSourceShowName
        }
        if (lineTargetShowName !== null) {
          cell.lineTargetShowName = lineTargetShowName
        }
        if (label !== null && label !== undefined) {
          cell.objectLabel = label
        }

        if (window.displayTypeComboStr.includes(cell.value.getAttribute('display')) && cell.value.getAttribute('selectQuote')) {
          // 引用节点编辑时更新label
          cell.value.setAttribute('label', label || name);
        }

        updateCellAttribute(cell, graph, data);
      }, personalityObj);
    }

    /**
     * 获取个性化的参数。
     * 根据对象类型返回特定的个性化属性配置。
     * @param {Object} cell - 图形单元对象
     * @returns {Object} 个性化属性对象
     */
    function getPersonalityAttrs(cell) {
      if (cell.value instanceof Object && cell.value.getAttribute('display') == 'SYSML_REQUIREMENT_XQJD') {
        return personalityObj = {
          xuqiuId: cell.value.getAttribute('xuqiuId')
        };
      }
    }

    // function showCellAttribute(cell, graph) {
    //   var metaId = cell.value.getAttribute('metaId');
    //   var quoteId = cell.value.getAttribute('quoteId');
    //   var objectId = cell.value.getAttribute('objectId');
    //   var labelName = cell.value.getAttribute('label');
    //   var name = cell.value.getAttribute('name');
    //   var params = '';
    //   if (cell.edge == 1) {
    //     var sourceId = cell.source != null ? cell.source.value.getAttribute('objectId') : '';
    //     var sourceName = cell.source != null ? cell.source.value.getAttribute('label') : '';
    //     var targetId = cell.target != null ? cell.target.value.getAttribute('objectId') : '';
    //     var targetName = cell.target != null ? cell.target.value.getAttribute('label') : '';
    //     params = '&sourceId=' + sourceId + '&targetId=' + targetId + '&sourceName=' + sourceName + '&targetName=' + targetName;
    //   }
    //
    //   var getUrl = '../object/showGraphObject.dhtml?eObjectId=' + metaId + '&objectId=' + objectId + '&name=' + name + '&modelId=' + modelId + '&quoteId=' + quoteId + params;
    //   window.parent.showDialogNoSave(getUrl, function(dialog) {
    //     var data = dialog.serializeMap();
    //     var valid = dialog.form('validate');
    //     if (!valid) {
    //       return;
    //     }
    //   }, null, 600, 800, null, metaId);
    // }


    /**
     * 编辑引用，切换引用。
     * 打开引用选择对话框，允许用户切换或修改对象的引用关系。
     * @param {Object} cell - 要编辑引用的图形单元对象
     * @param {Object} graph - 图形编辑器实例
     */
    function editQuoteNode(cell, graph) {
      let toggleQuoteCallBack = null
      if (window.toggleQuoteCallBack) {
        // connectSelect 连线选择时新增引用的回调
        toggleQuoteCallBack = window.toggleQuoteCallBack
      } else {
        toggleQuoteCallBack = function (data) {
          if (cell.value.getAttribute('label').indexOf('<div') > -1) {
            updateCellAttribute(cell, graph, {
              name: cell.value.getAttribute('name'),
              ...data
            });
          } else {
            updateCellAttribute(cell, graph, {
              name: cell.value.getAttribute('label'),
              ...data
            });
          }
        }
      }
      quoteDialog(resolveCell(cell), toggleQuoteCallBack, cell);
    }

    /**
     * 创建类的对象。
     * 为类对象创建实例，打开选择对话框让用户选择引用的对象。
     * @param {Object} cell - 要创建对象的图形单元
     * @param {Object} graph - 图形编辑器实例
     */
    function createClassObjNode(cell, graph) {

      var metaId = cell.value.getAttribute('metaId');
      var id = cell.value.getAttribute('objectId');
      var quoteId = cell.value.getAttribute('quoteId');
      var pId = cell.parent.value && cell.parent.value.getAttribute('objectId');
      var pMetaId = cell.parent.value && cell.parent.value.getAttribute('metaId');
      var getUrl = '../object/selectQuote.dhtml?eObjectId=' + metaId + '&modelId=' + modelId +
        '&quoteId=' + quoteId + '&parentId=' + pId + '&parentMetaId=' + pMetaId;
      var currentData;

      // 删除之前创建的对话框，避免重复创建
      deletePrevDialog();
      window.parent.showDialog(getUrl, function (dialog) {
        // 确定操作：用户点击确定按钮时的处理
        createClassObjNodeSureHandler(dialog, modelId, metaId, cell, graph);
      }, '引用选择', 800, 500, '选择', 'createClassObjNodeDialog', function (dialog) {
        // 取消操作：用户点击取消按钮时删除当前选择的单元格
        deleteCurrentSelectCell(dialog);
      });
    }

    /**
     * 推荐输入对象推荐资源。
     * 根据输入的应用app和服务组件信息，推荐合适的资源。
     * @param {Object} cell - 包含输入信息的图形单元对象
     * @param {Object} graph - 图形编辑器实例
     */
    function recommendResourceByInputs(cell, graph) {
      // 获取应用app与服务组件的ID信息
      var yyAppIds = ''; // 应用App的ID集合
      var yyAppMetaId = ''; // 应用App的元数据ID
      var fwzjIds = ''; // 服务组件的ID集合
      var fwzjMetaId = ''; // 服务组件的元数据ID
      for (var i = 0; i < cell.children.length; i++) {
        // 检查子元素是否为应用App类型
        if ('yingyongapp' == cell.children[i].value.getAttribute('name_en')) {
          if (yyAppIds == '') {
            yyAppIds = yyAppIds + cell.children[i].value.getAttribute('objectId');
          } else {
            yyAppIds = yyAppIds + ',' + cell.children[i].value.getAttribute('objectId');
          }
          if (yyAppMetaId == '') {
            yyAppMetaId = cell.children[i].value.getAttribute('metaId');
          }
        }

        // 检查子元素是否为服务组件类型
        if ('fuwuzj' == cell.children[i].value.getAttribute('name_en')) {
          if (fwzjIds == '') {
            fwzjIds = fwzjIds + cell.children[i].value.getAttribute('objectId');
          } else {
            fwzjIds = fwzjIds + ',' + cell.children[i].value.getAttribute('objectId');
          }
          if (fwzjMetaId == '') {
            fwzjMetaId = cell.children[i].value.getAttribute('metaId');
          }
        }
      }

      var metaId = cell.value.getAttribute('metaId');
      var id = cell.value.getAttribute('objectId');
      var quoteId = cell.value.getAttribute('quoteId');
      var getUrl = '../object/selectRecommend.dhtml?eObjectId=' + metaId + '&modelId=' + modelId + '&quoteId=' +
        quoteId + '&yyAppIds=' + yyAppIds + '&fwzjIds=' + fwzjIds + '&yyAppMetaId=' + yyAppMetaId + '&fwzjMetaId=' +
        fwzjMetaId;
      // 删除之前创建的dialog
      deletePrevDialog();
      window.parent.showDialog(getUrl, async function (dialog) {
          var selectRow = dialog.contents().find('table#quoteTable').eq(0).iDatagrid('getSelected');
          if (!selectRow) {
            return;
          }
          // 推荐类型
          var objType = selectRow.data_source;
          var currentData = selectRow;
          // // console.log(currentData);
          // 修改性能指标
          // currentData.xingnengzb = currentData.xingnengzb_new;
          // currentData.xingnengzb_new = '';

          var valueObj = cell.getValue();
          var clasName = cell.value.getAttribute('className');
          if ('sysMLRectangle' == cell.objType) {
            var labelTemp =
              '<div style="float: left;width: 100%;background-color: rgb(218, 232, 252)"><p style="margin:0px;margin-top:4px;text-align:center;">' +
              '&lt;&lt;' + clasName + '&gt;&gt;<br/>' +
              '<b>' + selectRow.name + '</b></p><hr style="margin-bottom: 0px;"/></div>';

            labelTemp = labelTemp + '<div style=\'float: left;width: 100%;margin-top: 5px;\'>' + getLabelTemp(cell
              .value.getAttribute('name_en'), currentData, selectRow.name) + '</div>';
            valueObj.setAttribute('label', labelTemp);
          } else {
            valueObj.setAttribute('label', currentData.name);
          }
          valueObj.setAttribute('name', currentData.name);
          if ('quote' == objType) { // 引用
            var quoteNode = mxUtils.createXmlDocument().createElement('quote');
            var sourceAttrs = cell.value.attributes;
            for (var i = 0; i < sourceAttrs.length; i++) {
              quoteNode.setAttribute(cell.value.attributes[i].name, cell.value.attributes[i].value);
            }
            quoteNode.setAttribute('quoteId', selectRow.id);
            valueObj = quoteNode;
          } else { // 复用
            var requestData = selectRow;
            requestData['eObjectId'] = metaId;
            requestData['modelId'] = modelId;

            await window.$axios.post('/object/updateGraphObjProperty.dhtml', {
              data: requestData,
            }).then((resp) => {
              if (resp.statusCode !== 200) {
                window.top.alertDialog(resp.message);
                return;
              }
              var id = resp.data.id;
              if (id !== null) {
                var currentData = selectRow;
                var valueObj = cell.getValue();
                var clasName = cell.value.getAttribute('className');
                if ('sysMLRectangle' === cell.objType) {
                  var labelTemp =
                    '<div style="float: left;width: 100%;background-color: rgb(218, 232, 252)"><p style="margin:0px;margin-top:4px;text-align:center;">' +
                    '&lt;&lt;' + clasName + '&gt;&gt;<br/>' +
                    '<b>' + selectRow.name + '</b></p><hr style="margin-bottom: 0px;"/></div>';

                  labelTemp = labelTemp + '<div style=\'float: left;width: 100%;margin-top: 5px;\'>' +
                    getLabelTemp(cell.value.getAttribute('name_en'), currentData, selectRow.name) + '</div>';
                  valueObj.setAttribute('label', labelTemp);
                  if (resp.data.id) {
                    valueObj.setAttribute('objectId', resp.data.id);
                  }
                } else {
                  valueObj.setAttribute('label', currentData.name);
                }
                valueObj.setAttribute('name', currentData.name);
                if (resp.data.id) {
                  valueObj.setAttribute('objectId', resp.data.id);
                }
              }
            }).catch(e => {
              // console.log("ajax fail.");
            })
          }

          // $.ajax({
          // 	url: '/object/updateGraphObject.dhtml?eObjectId=' + metaId + '&modelId=' + modelId,
          // 	type: "POST",
          // 	async: false,
          // 	data: currentData,
          // 	success: function (resp) {
          // 		if (resp.statusCode !== 200) {
          // 			window.top.alertDialog(resp.message);
          // 		}
          // 	}
          // });

          graph.getModel().setValue(cell, valueObj);
          dialog.iDialog('close');
        }, '推荐资源', 800, 500, '选择', 'editQuoteNodeDialog',
        function (dialog) {
          // 取消操作
          //deleteCurrentSelectCell(dialog);
        });
    }

    /**
     * 删除打开对话框时重复创建的元素。
     * 清理页面中残留的对话框、遮罩层等UI元素，防止界面混乱。
     */
    function deletePrevDialog() {
      var dvIframe = window.top.document.getElementById('designer-view-iframe');
      if (dvIframe !== null) {
        var frame = dvIframe.contentWindow.document.getElementById('frame');
        if (frame !== null) {
          // var dialogFarm = frame.contentWindow.document.getElementById('editQuoteNodeDialog');
          // if (dialogFarm !== null) {
          // 	dialogFarm.remove();
          // }
          var windowTop = frame.contentWindow.document.getElementsByClassName('panel window panel-htop');
          if (windowTop.length > 0) {
            for (let i = 0; i < windowTop.length; i++) {
              windowTop[i].remove();
            }
          }
          var windowShadow = frame.contentWindow.document.getElementsByClassName('window-shadow');
          if (windowShadow.length > 0) {
            for (let i = 0; i < windowShadow.length; i++) {
              windowShadow[i].remove();
            }
          }
          var windowMask = frame.contentWindow.document.getElementsByClassName('window-mask');
          if (windowMask.length > 0) {
            for (let i = 0; i < windowMask.length; i++) {
              windowMask[i].remove();
            }
          }
          var cellTip = frame.contentWindow.document.getElementById('celltip');
          if (cellTip !== null) {
            cellTip.remove();
          }
          var cellNumber = frame.contentWindow.document.getElementsByClassName('datagrid-cell-rownumber');
          if (cellNumber.length > 0) {
            for (let i = 0; i < cellNumber.length; i++) {
              cellNumber[i].remove();
            }
          }
        }
      }
    }

    function createClassObjNodeSureHandler(dialog, modelId, metaId, cell, graph) {

      var selectRow = dialog.contents().find('table#quoteTable').eq(0).iDatagrid('getSelected');
      if (!selectRow) {
        return;
      }
      var currentData = selectRow;
      var currentQuoteId = '0';
      if (selectRow.parent_class_id == '0') {
        currentQuoteId = selectRow.id;
      }
      var dataSource = selectRow.data_source;
      var postUrl = '../object/selectClassQuote.dhtml?object_id=' + selectRow.id + '&model_id=' + modelId +
        '&object_type=' + metaId + '&quote_type=' + currentQuoteId;
      if (dataSource == 'domain') {
        postUrl = postUrl + '&dataSource=' + dataSource;
      }

      window.$axios.post(postUrl, {}).then((resp) => {

        if (resp.statusCode == '200') {
          var valueObj = cell.getValue();
          if (dataSource == 'domain') {
            resp.data.name = selectRow.name;
            valueObj.setAttribute('objectId', selectRow.id);
            valueObj.setAttribute('dataSource', 'domain');
          }
          // var clasName = currentData.name;
          var clasName = cell.value.getAttribute('className');
          if ('sysMLRectangle' == cell.objType) {
            var labelTemp =
              '<div style="float: left;width: 100%;background-color: rgb(218, 232, 252)"><p style="margin:0px;margin-top:4px;text-align:center;">' +
              '&lt;&lt;' + clasName + '&gt;&gt;<br/>' +
              '<b>' + resp.data.name + '</b></p><hr style="margin-bottom: 0px;"/></div>';

            labelTemp = labelTemp + '<div style=\'float: left;width: 100%;margin-top: 5px;\'>' + getLabelTemp(cell
              .value.getAttribute('name_en'), currentData, resp.data.name) + '</div>';
            valueObj.setAttribute('label', labelTemp);
            valueObj.setAttribute('name', resp.data.name);
            if (resp.data.id) {
              valueObj.setAttribute('objectId', resp.data.id);
            }
            if (resp.data.sLabel != 'null' && resp.data.sLabel != null) {
              valueObj.setAttribute('sLabel', resp.data.sLabel);
            }
            graph.getModel().setValue(cell, valueObj);
            var objectId = resp.data.id || objectId; //被修改的对象ID
            //修改被引用的对象的Label
            var vertices = graph.getChildVertices();
            $.each(vertices, function (index, vertex) {
              if (typeof (vertex.value) != 'object') {
                return true;
              }
              if (vertex.value.nodeName == 'entity') {
                return true;
              } else {
                if (vertex.value.getAttribute('quoteId') == objectId) {
                  var currentValue = vertex.value;
                  currentValue.setAttribute('label', resp.data.name);
                  graph.getModel().setValue(vertex, currentValue);
                  return false;
                }
              }
            });
            dialog.iDialog('close');

          } else {

            var valueObj = cell.getValue();
            valueObj.setAttribute('label', resp.data.name);
            valueObj.setAttribute('name', resp.data.name);
            if (resp.data.id) {
              valueObj.setAttribute('objectId', resp.data.id);
            }
            if (resp.data.sLabel != 'null' && resp.data.sLabel != null) {
              valueObj.setAttribute('sLabel', resp.data.sLabel);
            }
            graph.getModel().setValue(cell, valueObj);
            var objectId = resp.data.id || objectId; //被修改的对象ID
            //修改被引用的对象的Label
            var vertices = graph.getChildVertices();
            $.each(vertices, function (index, vertex) {
              if (typeof (vertex.value) != 'object') {
                return true;
              }
              if (vertex.value.nodeName == 'entity') {
                return true;
              } else {
                if (vertex.value.getAttribute('quoteId') == objectId) {
                  var currentValue = vertex.value;
                  currentValue.setAttribute('label', resp.data.name);
                  graph.getModel().setValue(vertex, currentValue);
                  return false;
                }
              }
            });
            dialog.iDialog('close');
          }

        } else {
          window.parent.alertDialog(resp.message);
        }
      }).catch(e => {
        // console.log("ajax fail.");
      })
    }

    function deleteCurrentSelectCell(dialog) {

      // 如果没有选择数据
      const selectRow = dialog.contents().find('table#quoteTable').eq(0).iDatagrid('getSelected');

      if (!selectRow) {
        const graph = window.myEditor.editor.graph;
        const cells = graph.getSelectionCells();
        // 删除选择的 cell
        if (cells && cells.length === 1) {
          graph.escape();
          var select = graph.deleteCells(graph.getDeletableCells(graph.getSelectionCells()), true);
          if (select != null) {
            graph.setSelectionCells(select);
          }
        }
      }

    }

    function urlToBase64(url) {
      return new Promise((resolve, reject) => {
        let img = new Image();
        img.crossOrigin = 'Anonymous';
        img.src = url;
        let dataURL = ''
        img.onload = function () {
          let canvas = document.createElement('canvas');
          canvas.width = img.width;
          canvas.height = img.height;
          const ctx = canvas.getContext('2d');
          ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
          dataURL = canvas.toDataURL();
          resolve(dataURL)
          img = null;
          canvas = null;
        };
        img.onerror = function (error) {
          reject(error)
        }
      })

    }

    function imageToBase64(url, callback) {
      const xhr = new XMLHttpRequest();
      xhr.onload = function () {
        const render = new FileReader();
        render.onloadend = function () {
          callback(render.result)
        }
        render.readAsDataURL(new Blob([xhr.response], {type: 'image/*'}))
      }
      xhr.onerror = function () {
        callback()
      }
      xhr.open('GET', url)
      xhr.responseType = 'blob'
      xhr.send()
    }

    //修改背景图片
    function changeBackgroundImg(img, state) {
      drawioBus.$emit('editImage', function editImage(src,cellImageObj) {
        img.src = src;
        const graph = window.myEditor.editor.graph;
        graph.getModel().beginUpdate();
        const end = () => requestAnimationFrame(() => graph.getModel().endUpdate())

        // fix： 防止Actions中 img.onload覆盖以下设置
        mxEvent.addListener(img, 'load', function() {
          if (state == null) return end();

          var cells = graph.getSelectionCells();
          try {
            cells.forEach(function (cell) {
              if (cell && cell.isVertex() && mxUtils.isNode(cell.value)) {
                const name = cell.value.getAttribute('name')
                graph.getModel().setAttribute(cell, 'label', name);
                graph.getModel().setAttribute(cell, 'categoryId', cellImageObj.categoryId);
                graph.getModel().setAttribute(cell, 'imageId', cellImageObj.imageId);
                const style = cell.style

                let str =
                  'shape=image;verticalLabelPosition=bottom;labelBackgroundColor=none;verticalAlign=top;aspect=fixed;imageAspect=0;image=' +
                  src + ';';
                style.includes('container=1') && (str += 'container=1;')
                graph.getModel().setStyle(cell, str);
              }
            })
          } finally {
            end()
          }
        })

        mxEvent.addListener(img, 'error', end)
      })
    }

    /**
     * 计算下标的函数。
     * 根据已有数量和最大编号计算新对象的序号。
     * @param {number} count - 同类模型拥有此对象的数量
     * @param {number} bigNum - 同类模型名中有数字的最大值
     * @param {number} maxBigNum - 当前记录的最大数量
     * @returns {number} 计算后的新序号
     */
    function calcNumber(count, bigNum, maxBigNum) {
      count = parseInt(count || 0); // 同类模型拥有此对象的数量
      bigNum = parseInt(bigNum || 0); // 同类模型名中有数字的最大值
      maxBigNum = Math.max(maxBigNum, bigNum); // 更新最大数量
      maxBigNum = count > maxBigNum ? count + 1 : maxBigNum + 1;
      return maxBigNum;
    }

    /**
     * 获取创建关系线时的关系线标签。
     * 返回关系线的显示标签，默认格式为"源名称_目标名称"。
     * @param {Object} edge - 关系线对象
     * @param {Object} source - 源节点对象
     * @param {Object} target - 目标节点对象
     * @returns {string} 关系线的标签文本
     */
    function getCreateEdgeLabel(edge, source, target) {
      return edge.value.getAttribute('sysmlTitle') || edge.value.getAttribute("label") || `${resolveCell(source).name}_${resolveCell(target).name}`
    }

    const getRealTerminal = (cell, source) => {
      const terminal = source && source instanceof mxCell ? source : cell[source ? 'source' : 'target']
      if (!terminal) return
      return cell.getAttribute('tooltip') === '期间约束' || terminal.style.indexOf('isSequenceSupport=1') > -1 ? terminal.parent : terminal
    }

    /**
     * 获取对象在其他模型中的数量和名称里最大的数字。
     * 查询服务端获取对象的命名信息，计算新对象的序号。
     * @param {Object} nodeValue - 节点的值对象
     * @param {Object} cell - 图形单元对象
     * @param {Object} source - 源节点（用于关系线）
     * @param {Object} target - 目标节点（用于关系线）
     * @returns {Promise<string>} 返回计算后的对象名称
     */
    async function getObjectNameInfo(nodeValue, cell, source, target) {
      if (typeof (nodeValue) != 'object') {
        return;
      }
      if (nodeValue.tagName === 'quote') {
        return nodeValue.getAttribute('name');
      }

      if (cell.isEdge()) {
        return getCreateEdgeLabel(cell, getRealTerminal(cell, source || true), getRealTerminal(cell, target || false))
      }

      var eObjectId = nodeValue.getAttribute('metaId');
      var eName = '';
      var count = 0; // 其他模型拥有此对象的数量
      var bigNum = 0; // 其他模型名中有数字的最大值

      const {statusCode, data} = await window.$axios.get(contextPath + '/object/getObjectNameInfo', {
        params: {
          'modelId': modelId,
          'eObjectId': eObjectId
        },
      })
      if (statusCode === 200 && data) {
        const {
          eName = '',
          count = 0, // 记录<最大数量>
          bigNum = 0, // 记录<最大编号>
          identityCodeBigNum = 0,
          identityCodeCount = 0,
          identityCodePrefix = '',
        } = data
        const metaId = nodeValue.getAttribute('metaId')
        // 计算标签序号：用于对象名称的数字后缀
        window.numberProxy.maxBigNum[metaId] = calcNumber(
          count,
          bigNum,
          window.numberProxy.maxBigNum[metaId] || 0,
        );
        // 计算右下角的标识序号：用于对象右下角显示的标识编号
        window.numberProxy.maxSuffixCodeNum[metaId] = calcNumber(
          identityCodeCount,
          identityCodeBigNum,
          window.numberProxy.maxSuffixCodeNum[metaId] || 0,
        );
        // 设置对象的后缀标识：引用的序号通过selectQuote接口获取
        cell.value.setAttribute('_suffix', identityCodePrefix + window.numberProxy.maxSuffixCodeNum[metaId]);
        // myEditor.editor.graph.addCornerMarkOverlay(cell);
        return eName + window.numberProxy.maxBigNum[metaId];
      }
      return nodeValue.getAttribute('name');

      var defaultParent = myEditor.editor.graph.getDefaultParent()

      // 获取所有图形单元，包括嵌套的子级元素
      var cells = defaultParent ? myEditor.editor.graph.getModel().getDescendants(defaultParent).filter(function (c) { return c !== defaultParent }) : null;

      if (cells == null) {
        if (count > maxBigNum) {
          return eName + count;
        } else {
          var returnName = eName + (maxBigNum + 1);
          maxBigNum = maxBigNum + 1;
          return returnName;
        }
      }
      $.each(cells, function (index, currentCell) {
        if (currentCell.getValue() != null && typeof (currentCell.getValue()) == 'object' && currentCell
          .getValue().getAttribute('metaId') == eObjectId &&
          currentCell.getValue().getAttribute('objectId') == '') {
          count++;
          var currentName = currentCell.getValue().getAttribute('label');
          if (currentName.startsWith(eName)) {
            currentName = currentName.substring(eName.length);
            if (currentName.length > 0 && /^[1-9][0-9]*/i.test(currentName) && parseInt(currentName) > bigNum) {
              bigNum = parseInt(currentName);
            }
          }
        }
      });
      if (count > maxBigNum) {
        return eName + (count + n);
      } else {
        var returnName = eName + (maxBigNum + n + 1);
        maxBigNum = maxBigNum + 1;
        return returnName;
        //return eName+(bigNum+1+n);
      }

    }

    /**
     * 获取对象的标签。
     * 通过调用getObjectNameInfo函数获取对象的显示标签。
     * @param {Object} cell - 图形单元对象
     * @param {Object} source - 源节点对象
     * @param {Object} target - 目标节点对象
     * @returns {Promise<string>} 返回对象的标签文本
     */
    async function getObjectLabelByCell(cell, source, target) {
      return await getObjectNameInfo(cell.getValue(), cell, source, target);
    }

    function getCellLableByEidt2(valueObjData, cell, objName, attrClassSb) {

      if ('sysMLRectangle' === cell.objType) {
        var label = cell.value.getAttribute('label');
        var start = label.substr(0, label.indexOf('<b>') + 3);
        var end = label.substr(label.indexOf('</b>'));
        label = start + objName + end;

        var objLabelsValue = '';
        $.each(valueObjData, function (key, value) {
          if ('objLabels' == key) {
            objLabelsValue = value;
          }
        });

        var nameEn = cell.value.getAttribute('name_en');
        var attrList = getObjAttrsClass(nameEn, attrClassSb);
        var labelTemp = label.substr(0, label.indexOf('</div>') + 6);
        var headFlag = 0;
        if (attrList != null) {
          for (var i = 0; i < attrList.length; i++) {
            var classObj = attrList[i];
            var returnLable = getObjLableByAttrClass(headFlag, classObj, valueObjData, objLabelsValue);
            if ('' != returnLable) {
              labelTemp = labelTemp + returnLable;
              if (headFlag == 0) {
                headFlag = 1;
              }
            }
          }
        }
        return labelTemp;
      } else {
        return objName;
      }

    }

    function getLabelTemp(nameEn, currentData, name) {

      var labelTemp = '';
      var attrList = getObjAttrsClass(nameEn);

      var headFlag = 0;
      for (var i = 0; i < attrList.length; i++) {
        var classObj = attrList[i];
        var returnLable = getObjLableByAttrClass(headFlag, classObj, currentData, null, name);
        if ('' != returnLable) {
          labelTemp = labelTemp + returnLable;
          if (headFlag == 0) {
            headFlag = 1;
          }
        }
      }
      return labelTemp;
    }

    /**
     * 获取属性的分类。
     * 根据对象的英文名称获取其属性分类配置信息。
     * @param {string} name - 对象的英文名称
     * @param {string} attrClassificationsNew - 新的属性分类配置字符串
     * @returns {Array|null} 属性分类数组，如果未找到则返回null
     */
    function getObjAttrsClass(name, attrClassificationsNew) {

      var nameEN = name;

      var attrClassificationList = [];
      if (attrClassificationsNew != null) {
        attrClassificationList = attrClassificationsNew.split('==');
      } else {
        // 取页面上的全局属性分类变量值
        attrClassificationList = attrClassifications.split('==');
      }

      if (attrClassificationList.length > 0) {
        for (var i = 0; i < attrClassificationList.length; i++) {
          var obj = attrClassificationList[i];
          if (obj.indexOf(nameEN) >= 0) {
            var enNameLength = nameEN.length;
            var lastAttrClassifications = obj.substr(enNameLength + 3);
            if (lastAttrClassifications.indexOf('==') >= 0) {
              lastAttrClassifications = lastAttrClassifications.substr(0, lastAttrClassifications.length - 4);
            } else {
              lastAttrClassifications = lastAttrClassifications.substr(0, lastAttrClassifications.length - 2);
            }

            var attrList = lastAttrClassifications.split(',,');
            return attrList;
          }
        }
      }
      return null;
    }

    /**
     * 根据属性分类生成对应的标签。
     * 根据属性分类配置生成对象的显示标签内容。
     * @param {number} headFlag - 标题标识，用于控制样式
     * @param {string} classObj - 分类对象字符串
     * @param {Object} valueObjData - 值对象数据
     * @param {string} objLabelsValue - 对象标签值
     * @param {string} quoteName - 引用名称
     * @param {boolean} isNew - 是否为新对象
     * @returns {string} 生成的标签HTML字符串
     */
    function getObjLableByAttrClass(headFlag, classObj, valueObjData, objLabelsValue, quoteName, isNew) {
      var classNameIndex = classObj.indexOf('=');
      var className = classObj.substr(0, classNameIndex);
      var temp = '';
      if (headFlag > 0) {
        temp = '<hr/><p style="font-size:10px;margin:0px;text-align:center;"><i>' + className + '</i></p>';
      } else {
        temp = '<p style="font-size:5px;margin:0px;text-align:center;"><i>' + className + '</i></p>';
      }
      var classAttrStr = classObj.substr(classNameIndex + 1, classObj.length - (classNameIndex + 1));
      var classAttrList = classAttrStr.split(',');
      var attrTem = '';
      for (var i = 0; i < classAttrList.length; i++) {

        var attObj = classAttrList[i];
        var indexNameEn = attObj.indexOf('|');
        var nameEn = attObj.substr(0, indexNameEn);
        var nameChina = attObj.substr(indexNameEn + 1, attObj.length - (indexNameEn + 1));
        var label = '';
        if (quoteName != '' && quoteName != null) {
          if ('name' == nameEn) {
            label = quoteName;
            // label = "";
          } else {
            label = getValueByNameEnQuote(nameEn, valueObjData);
          }
        } else {
          if (isNew) {
            label = getValueByNameEn(nameEn, valueObjData, objLabelsValue);
          } else {
            label = getValueByNameEnQuote(nameEn, valueObjData);
          }

        }

        var attrTemp = nameChina + '：' + label;
        attrTem = attrTem + '<p style="margin:0px;margin-left:8px;text-align:left;">' + attrTemp + '</p>';
      }
      if (attrTem != '' && null != attrTem) {
        return temp + attrTem;
      }

      return '';
    }

    /**
     * 根据英文名获取值。
     * 从值对象数据中根据英文属性名获取对应的值。
     * @param {string} name - 英文属性名
     * @param {Array} valueObjData - 值对象数据数组
     * @param {string} objLabelsValue - 对象标签值字符串
     * @returns {string} 获取到的属性值
     */
    function getValueByNameEn(name, valueObjData, objLabelsValue) {

      // if("name" == name || "zhishuxing" == name){
      // 	return "";
      // }

      // 从表单数据中获取普通输入框的值
      var result = '';
      for (var i = 0; i < valueObjData.length; i++) {
        if (valueObjData[i].name == name) {
          result = valueObjData[i].value;
          if (result == null) {
            result = '';
          } else if (result.length > 8) {
            result = result.substr(0, 8) + '...';
          }
        }
      }

      // 判断对象标签值中是否存在该属性
      var label = '';
      var nameTemp = name + '|';
      var len = nameTemp.length;
      if (null != objLabelsValue && '' != objLabelsValue) {
        var nameIndex = objLabelsValue.indexOf(nameTemp);
        if (nameIndex >= 0) {
          objLabelsValue = objLabelsValue.substr(nameIndex);
          var index2 = objLabelsValue.indexOf('|');
          var index3 = objLabelsValue.indexOf(',,');

          if (index3 < 0) {
            label = objLabelsValue.substr(index2 + 1);
          } else {
            var index4 = index3 - index2;
            label = objLabelsValue.substr(index2 + 1, index4 - 1);
          }

          if (null == label || 'null' == label) {
            label = '';
          }

          if (label.length > 8) {
            label = label.substr(0, 8) + '...';
          }
        }
      }

      if (result != '') {
        if (label != '') {
          return label;
        }
        return result;
      }

      return '';
    }

    /**
     * 根据英文名获取引用对象的值。
     * 从引用数据中根据英文属性名获取对应的值，支持文本和标签格式。
     * @param {string} name - 英文属性名
     * @param {Object} currentData - 当前数据对象
     * @returns {string} 获取到的引用值
     */
    function getValueByNameEnQuote(name, currentData) {

      // if("name" == name || "zhishuxing" == name){
      //     return "";
      // }

      // 从引用数据中获取属性值
      var lable = '';
      var label_text = '';
      $.each(currentData, function (key, value) {
        if (name == key) {
          if (value != null) {
            lable = value.replace('\n', '');
          }
        }
        var name_text = name + '_text';
        if (name_text == key) {
          if (value != null) {
            label_text = value.replace('\n', '');
          }
        }
      });

      if (label_text != '') {
        lable = label_text;
      }

      if (null == lable || 'null' == lable) {
        lable = '';
      }

      if (lable.length > 8) {
        lable = lable.substr(0, 8) + '...';
      }

      return lable;
    }

    function pageLeaveAutoSave() {
      //const saveButton = window.document.getElementById("gesprite-save");
      //// console.log(saveButton);
    }

    $(document).ready(function () {
      window.parent.postMessage({
        status: 'init'
      });
      drawioBus.$emit('graphPageReady', window);

      // MouseMoveShowYe llowCircle()
      // 是否是时序图
      // isTimeSequenceDiagramView = isTimeSequenceDiagram();
      // pageLeaveAutoSave();
    });

  </script>
  <!-- zTree组件的右键上下文菜单 -->
  <div id="rMenu" style="display: none">
    <!--
  <div><a href="#" class="right-menu-item" onclick="zTreeOnRightClickAdd();">增加</a></div>
  <div><a href="#" class="right-menu-item" onclick="zTreeOnRightClickDell();">删除</a></div>
  -->
    <div><a href="#" class="right-menu-item" onclick="zTreeOnRightClickUpdate();">修改</a></div>
    <!--
  <div><a href="#" class="right-menu-item" onclick="zTreeOnRightClickSearch();">查询</a></div>
  -->
  </div>

  <!-- zTree事件节点的右键上下文菜单 -->
  <div id="rMenu_event" style="display: none">
    <!--
  <div><a href="#" class="right-menu-item" onclick="zTreeOnRightClickAdd();">增加</a></div>
  <div><a href="#" class="right-menu-item" onclick="zTreeOnRightClickDell();">删除</a></div>
  -->
    <div><a href="#" class="right-menu-item" onclick="zTreeOnRightClickDell();">删除</a></div>
    <div><a href="#" class="right-menu-item" onclick="zTreeOnRightClickUpdate();">修改</a></div>
    <!--
  <div><a href="#" class="right-menu-item" onclick="zTreeOnRightClickSearch();">查询</a></div>
  -->
  </div>
</body>

</html>
